﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using DotaHelp.Models;
using System.Data.Objects;
using System.Data.Objects.SqlClient;
using DotaHelp.Helpers;

namespace DotaHelp.Controllers
{
    public class PurchasesRulesController : Controller
    {
		DotaModel model = new DotaModel();

		protected override void Dispose(bool disposing)
		{
			base.Dispose(disposing);
			model.Dispose();
			
		}      

		[OutputCache(Duration=60, Location=System.Web.UI.OutputCacheLocation.Server, VaryByCustom="User")]
        public ActionResult List(string type = "", int id = -1)
        {
			if (type == "ItemRule" && id != -1)
			{
				return RedirectToRoute("Item", new { id = model.PurchaseItemRules.First(r=>r.Id == id).Item1Id });
			}
			else if (type == "HeroRule" && id != -1)
			{
				return RedirectToRoute("Item", new { id = model.PurchaseHeroRules.First(r => r.Id == id).ItemId });
			}

			var heroRules = 
				from r in model.PurchaseHeroRules
				let comments = model.Comments.Where(c => !c.IsDeleted && c.Url == "/HeroRule/" + SqlFunctions.StringConvert((double?)r.Id).Trim()).OrderBy(c => c.PostDate)
				where !r.IsDeleted
				orderby r.Hero.Name
				select new PurchasesHeroRuleAndComments() {Rule = r, Hero = r.Hero, Item = r.Item, Comments = comments};

			var itemRules =
				from r in model.PurchaseItemRules
				let comments = model.Comments.Where(c => !c.IsDeleted && c.Url == "/ItemRule/" + SqlFunctions.StringConvert((double?)r.Id).Trim()).OrderBy(c => c.PostDate)
				where !r.IsDeleted
				orderby r.Item1Id
				select new PurchasesItemRuleAndComments() { Rule = r, Item1 = r.Item, Item2 = r.Item1, Comments = comments };

			return View(new Tuple<IEnumerable<PurchasesHeroRuleAndComments>, IEnumerable<PurchasesItemRuleAndComments>>(heroRules, itemRules));
        }

		[ChildActionOnly]
		public string RatingHeroRule(int id, bool isPlus)
		{
			var rule = model.PurchaseHeroRules.First(h => h.Id == id);
			rule.Raiting += isPlus ? 1 : -1;
			model.SaveChanges();
			return rule.Raiting.ToString();
		}

		[ChildActionOnly]
		public string RatingItemRule(int id, bool isPlus)
		{
			var rule = model.PurchaseItemRules.First(h => h.Id == id);
			rule.Raiting += isPlus ? 1 : -1;
			model.SaveChanges();
			return rule.Raiting.ToString();
		}

		#region Hero		
		
		public ActionResult HeroRulesListForHero(int heroId)
		{
			ViewBag.HeroId = heroId;
			var heroRules =
				from r in model.PurchaseHeroRules
				let comments = model.Comments.Where(c => !c.IsDeleted && c.Url == "/HeroRule/" + SqlFunctions.StringConvert((double?)r.Id).Trim()).OrderBy(c => c.PostDate)
				where !r.IsDeleted && r.HeroId == heroId
				orderby r.Hero.Name
				select new PurchasesHeroRuleAndComments() { Rule = r, Hero = r.Hero, Item = r.Item, Comments = comments };

			return Request.IsAjaxRequest()?(ActionResult)PartialView(heroRules):View(heroRules);
		}


		[Authorize()]
		[ValidateInput(false)]
		[HttpPost]
		public ActionResult AddHeroRule(int heroId, string itemId, string severity, string text)
		{
			var hero = model.Heroes.First(h => h.Id == heroId);
			foreach (var id2 in itemId.Split(',').Select(_ => int.Parse(_.Trim())))
			{
				var rule = hero.PurchaseHeroRules.FirstOrDefault(r => r.ItemId == id2);
				if (rule != null)
				{
					if (rule.IsDeleted == false)
					{
						throw new MessageException("Такое правило уже существует");
					}
					rule.IsDeleted = false;
					rule.Severity = severity;
					rule.Text = text;
					rule.Author = HttpContext.PrepareUserName(User.Identity.Name);
				}
				else
				{
					rule = new PurchaseHeroRule();
					rule.HeroId = heroId;
					rule.ItemId = id2;
					rule.Severity = severity;
					rule.Text = text;
					rule.IsDeleted = false;
					rule.Author = HttpContext.PrepareUserName(User.Identity.Name);
					model.AddToPurchaseHeroRules(rule);
				}
			}

			model.SaveChanges();

			return RedirectToRoute("Hero", new { id = heroId });
		}

		[Authorize]
		[HttpPost]
		public ActionResult RemoveHeroRule(int id)
		{
			var rule = model.PurchaseHeroRules.FirstOrDefault(r => r.Id == id);
			rule.IsDeleted = true;
			model.SaveChanges();
			return RedirectToRoute("Hero", new { id = rule.HeroId });
		}

		[Authorize]
		[HttpPost]
		public ActionResult UpdateHeroRuleSeverity(int id, string severity)
		{
			var rule = model.PurchaseHeroRules.FirstOrDefault(r => r.Id == id);
			rule.Severity = severity;
			model.SaveChanges();
			return RedirectToRoute("Hero", new { id = rule.HeroId });
		}
		#endregion
		#region Items

		
		public ActionResult ItemRulesListForHero(int itemId)
		{
			ViewBag.ItemId = itemId;

			var itemRules =
				from r in model.PurchaseItemRules
				let comments = model.Comments.Where(c => !c.IsDeleted && c.Url == "/ItemRule/" + SqlFunctions.StringConvert((double?)r.Id).Trim()).OrderBy(c => c.PostDate)
				where !r.IsDeleted && (r.Item1Id == itemId || r.Item2Id == itemId)
				orderby r.Item1Id
				select new PurchasesItemRuleAndComments() { Rule = r, Item1 = r.Item, Item2 = r.Item1, Comments = comments };

			var heroRules =
				from r in model.PurchaseHeroRules
				let comments = model.Comments.Where(c => !c.IsDeleted && c.Url == "/HeroRule/" + SqlFunctions.StringConvert((double?)r.Id).Trim()).OrderBy(c => c.PostDate)
				where !r.IsDeleted && r.ItemId == itemId
				orderby r.Hero.Name
				select new PurchasesHeroRuleAndComments() { Rule = r, Hero = r.Hero, Item = r.Item, Comments = comments };

			return PartialView(Tuple.Create(itemRules.ToArray(), heroRules.ToArray()));
		}

		[Authorize()]
		[ValidateInput(false)]
		[HttpPost]
		public ActionResult AddItemRule(int item1Id, string item2Id, string severity, string text)
		{
			foreach (var id2 in item2Id.Split(',').Select(_ => int.Parse(_.Trim())))
			{
				var rule = model.PurchaseItemRules.FirstOrDefault(r => r.Item1Id == item1Id && r.Item2Id == id2)
					?? model.PurchaseItemRules.FirstOrDefault(r => r.Item1Id == id2 && r.Item2Id == item1Id);
				if (rule != null)
				{
					if (rule.IsDeleted == false)
					{
						throw new MessageException("Такое правило уже существует");
					}
					rule.IsDeleted = false;
					rule.Severity = severity;
					rule.Text = text;
					rule.Author = HttpContext.PrepareUserName(User.Identity.Name);
				}
				else
				{
					rule = new PurchaseItemRule();
					rule.Item1Id = item1Id;
					rule.Item2Id = id2;
					rule.Severity = severity;
					rule.Text = text;
					rule.IsDeleted = false;
					rule.Author = HttpContext.PrepareUserName(User.Identity.Name);
					model.AddToPurchaseItemRules(rule);
				}
			}
			model.SaveChanges();

			return RedirectToRoute("Item", new { id = item1Id });
		}

		[Authorize]
		[HttpPost]
		public ActionResult RemoveItemRule(int id)
		{
			var rule = model.PurchaseItemRules.FirstOrDefault(r => r.Id == id);
			rule.IsDeleted = true;
			model.SaveChanges();
			return RedirectToRoute("Item", new { id = rule.Item1Id });
		}

		[Authorize]
		[HttpPost]
		public ActionResult UpdateItemRuleSeverity(int id, string severity)
		{
			var rule = model.PurchaseItemRules.FirstOrDefault(r => r.Id == id);
			rule.Severity = severity;
			model.SaveChanges();
			return RedirectToRoute("Item", new { id = rule.Item1Id });
		}
		#endregion
	}

	public class PurchasesHeroRuleAndComments
	{
		public PurchaseHeroRule Rule {get; set;}
		public Hero Hero { get; set; }
		public Item Item { get; set; }
		public IEnumerable<Comment> Comments {get; set;}
	}


	public class PurchasesItemRuleAndComments
	{
		public PurchaseItemRule Rule { get; set; }
		public Item Item1 { get; set; }
		public Item Item2 { get; set; }
		public IEnumerable<Comment> Comments { get; set; }
	}
}
